package com.ckm.datasource;

import com.ckm.provider.DynamicMongoSourceProvider;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RequiredArgsConstructor
public abstract class AbstractRoutingMongoSource implements InitializingBean {

    private Map<Object,MongoDatabaseFactory> targetMongoDatabaseFactories;

    @Getter
    @Setter
    private MongoDatabaseFactory defaultTargetMongoDatabaseFactory;

    private final List<DynamicMongoSourceProvider> providers;

    protected abstract Object determineCurrentLookupKey();

    protected MongoDatabaseFactory determineMongoDatabaseFactory(){
        Assert.notNull(this.targetMongoDatabaseFactories, "数据源路由未初始化");
        Object lookupKey = this.determineCurrentLookupKey();
        MongoDatabaseFactory mongoDatabaseFactory = this.targetMongoDatabaseFactories.get(lookupKey);
        if (mongoDatabaseFactory==null&&lookupKey==null){
            mongoDatabaseFactory = this.defaultTargetMongoDatabaseFactory;
        }
        if (mongoDatabaseFactory == null){
            throw new IllegalStateException("用 [" + lookupKey + "] 找不到对应数据源");
        }
        return mongoDatabaseFactory;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        HashMap<String, MongoDatabaseFactory> mongoSources = new HashMap<>();
        for (DynamicMongoSourceProvider provider : providers) {
            Map<String, MongoDatabaseFactory> loadMongoSource = provider.loadMongoSource();
            if (loadMongoSource!=null){
                mongoSources.putAll(loadMongoSource);
            }
        }
        for (Map.Entry<String, MongoDatabaseFactory> entry : mongoSources.entrySet()) {
            addMongoSource(entry.getKey(), entry.getValue());
        }
    }

    public synchronized void addMongoSource(String key,MongoDatabaseFactory mongoDatabaseFactory){
        if (this.targetMongoDatabaseFactories==null){
            log.info("创建数据源集合");
            this.targetMongoDatabaseFactories = new HashMap<>();
        }
        this.targetMongoDatabaseFactories.put(key,mongoDatabaseFactory);
        log.info("加载数据源:{}",key);
    }

    public synchronized void removeMongoSource(String key){
        if (key == null || key.equals("")){
            throw new RuntimeException("key不能为空");
        }
        if (targetMongoDatabaseFactories.containsKey(key)){
            targetMongoDatabaseFactories.remove(key);
            log.info("删除数据源： {}",key);
        }else {
            log.warn("找不到该{},指向的数据源",key);
        }
    }
}
